package cz.muni.fi.pa165.web;

import cz.muni.fi.pa165.portalnahouby.api.dto.ForestDTO;
import cz.muni.fi.pa165.portalnahouby.api.dto.PickerDTO;
import cz.muni.fi.pa165.portalnahouby.api.dto.VisitDTO;
import cz.muni.fi.pa165.portalnahouby.api.serviceinterface.ForestService;
import cz.muni.fi.pa165.portalnahouby.api.serviceinterface.PickerService;
import cz.muni.fi.pa165.portalnahouby.api.serviceinterface.VisitService;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import net.sourceforge.stripes.action.*;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@UrlBinding("/visits/{$event}/{visit.id}")
public class VisitsActionBean implements ActionBean {

	final static Logger log = LoggerFactory.getLogger(VisitsActionBean.class);
	private ActionBeanContext context;
	@SpringBean
	protected VisitService visitManager;
	@SpringBean
	protected PickerService pickerManager;
	@SpringBean
	protected ForestService forestManager;
        
        private int show;

        public int getShow() {
            return show;
        }

        public void setShow(int show) {
            this.show = show;
        }

	@DefaultHandler
	public Resolution all() {
		log.debug("all()");
		return new ForwardResolution("/visit.jsp");
	}

	public List<VisitDTO> getAllVisits() {
		return visitManager.getAllVisits();
	}

	@Override
	public void setContext(ActionBeanContext context) {
		this.context = context;
	}

	@Override
	public ActionBeanContext getContext() {
		return context;
	}
	@ValidateNestedProperties(value = {
		@Validate(on = {"add", "save"}, field = "visitDate", required = true),
		@Validate(on = {"add", "save"}, field = "description", required = true, maxlength = 255),
                @Validate(on = {"add", "save"}, field = "forest.id", required = true),
                @Validate(on = {"add", "save"}, field = "picker.id", required = true),
                @Validate(on = {"forest"}, field = "forest", required = true),
                @Validate(on = {"date"}, field = "forest", required = true),
                @Validate(on = {"picker"}, field = "forest", required = true)
	})
	private VisitDTO visit;

	public Resolution add() {
		log.debug("add() visit={}", visit);
		String ids = context.getRequest().getParameter("visit.picker.id");
		if (ids != null) {
			visit.setPicker(pickerManager.findPicker(Long.parseLong(ids)));
		}
		ids = context.getRequest().getParameter("visit.forest.id");
		if (ids != null) {
			visit.setForest(forestManager.findForest(Long.parseLong(ids)));
		}
		visitManager.addVisit(visit);
		return new RedirectResolution(this.getClass(), "all");
	}
        
        public List<VisitDTO> getVisits() {
        List<VisitDTO> result = new ArrayList<VisitDTO>();
        String ids;
            switch (show) {
                default:
                case 1:
                    result = visitManager.getListByForest();
                    break;
                case 2:
                    ids = context.getRequest().getParameter("visit.forest");
                    result = visitManager.getListOfForestByDate(forestManager.findForest(Long.parseLong(ids)));
                    break;
                case 3:
                    ids = context.getRequest().getParameter("visit.forest");
                    result = visitManager.getListOfForestByPicker(forestManager.findForest(Long.parseLong(ids)));
                    break;
            }
            return result;
        }
        
        public Resolution forest() { //sorting visits by forest
		log.debug("forest() visit={}", visit);
                show = 1;
		return new ForwardResolution(this.getClass(), "all");
	}

        public Resolution date() { //sorting visits by date
		log.debug("date() visit={}", visit);
                show = 2;
		return new ForwardResolution(this.getClass(), "all");
        }
        
        public Resolution picker() { //sorting visits by picker
		log.debug("picker() visit={}", visit);
                show = 3;
		return new ForwardResolution(this.getClass(), "all");
	}
        
	public VisitDTO getVisit() {
		return visit;
	}

	public void setVisit(VisitDTO visit) {
		this.visit = visit;
	}

	@Before(stages = LifecycleStage.BindingAndValidation, on = {"edit", "save"})
	public void loadVisitFromDatabase() {
		String ids = context.getRequest().getParameter("visit.id");
		if (ids == null) {
			return;
		}
		visit = visitManager.findVisit(Long.parseLong(ids));
	}

	public Resolution edit() {
		SecurityActionBean securityActionBean = new SecurityActionBean();
		securityActionBean.setContext(getContext());
		if( securityActionBean.isCurrentUserID(visit.getPicker().getId()))
		{
			return new ForwardResolution("/visitedit.jsp");
		}
		else
		{
			return new RedirectResolution("/not_enough_rights.jsp");
		}
	}

	public Resolution save() {
		String ids = context.getRequest().getParameter("visit.picker.id");
		if (ids != null) {
			visit.setPicker(pickerManager.findPicker(Long.parseLong(ids)));
		}
		ids = context.getRequest().getParameter("visit.forest.id");
		if (ids != null) {
			visit.setForest(forestManager.findForest(Long.parseLong(ids)));
		}
		visitManager.editVisit(visit);
		return new RedirectResolution(this.getClass(), "all");
	}

	@RequiresAdmin
	public Resolution delete() {
		log.debug("delete({})", visit.getId());
		visitManager.deleteVisit(visit.getId());
		return new RedirectResolution(this.getClass(), "all");
	}
	
	public List<PickerDTO> getPickers()
	{
		PickerDTO loggedUser = (PickerDTO) getContext().getRequest().getSession().getAttribute("loggedUser");
		List<PickerDTO> managerResult = pickerManager.getAllPickers();
		List<PickerDTO> result = new LinkedList<PickerDTO>();
		if( loggedUser != null )
		{
			for( PickerDTO picker : managerResult )
			{
				if( loggedUser.getIsAdmin() || picker.equals(loggedUser) )
				{
					result.add(picker);
				}
			}
		}
		return result;
	}
	
	public List<ForestDTO> getForests()
	{
		List<ForestDTO> result = forestManager.getAllForests();
		return result;
	}
}